/*
 * $Id:   Broadcom SDK $
 * $Copyright: Copyright 2011 Broadcom Corporation.
 * This program is the proprietary software of Broadcom Corporation
 * and/or its licensors, and may only be used, duplicated, modified
 * or distributed pursuant to the terms and conditions of a separate,
 * written license agreement executed between you and Broadcom
 * (an "Authorized License").  Except as set forth in an Authorized
 * License, Broadcom grants no license (express or implied), right
 * to use, or waiver of any kind with respect to the Software, and
 * Broadcom expressly reserves all rights in and to the Software
 * and all intellectual property rights therein.  IF YOU HAVE
 * NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
 * IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
 * ALL USE OF THE SOFTWARE.  
 *  
 * Except as expressly set forth in the Authorized License,
 *  
 * 1.     This program, including its structure, sequence and organization,
 * constitutes the valuable trade secrets of Broadcom, and you shall use
 * all reasonable efforts to protect the confidentiality thereof,
 * and to use this information only in connection with your use of
 * Broadcom integrated circuit products.
 *  
 * 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
 * PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
 * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
 * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY
 * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
 * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
 * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
 * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
 * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
 * 
 * 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
 * BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
 * INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
 * ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
 * TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
 * THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
 * WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
 * ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
 *
 * File:    bfd.h
 */

#ifndef BFD_H_
#define BFD_H_

#ifdef BCM_UKERNEL
  /* Build for uKernel not SDK */
  #include "sdk_typedefs.h"
#endif

/*
 * BFD session states
 */
#define BFD_SESSION_STATE_ADMIN_DOWN        0
#define BFD_SESSION_STATE_DOWN              1
#define BFD_SESSION_STATE_INIT              2
#define BFD_SESSION_STATE_UP                3

/*
 * Authentication types
 */
#define BFD_AUTH_TYPE_RSVD_INVALID              0
#define BFD_AUTH_TYPE_SIMPLE_PASSWORD           1
#define BFD_AUTH_TYPE_KEYED_MD5                 2
#define BFD_AUTH_TYPE_METICULOUS_KEYED_MD5      3
#define BFD_AUTH_TYPE_KEYED_SHA1                4
#define BFD_AUTH_TYPE_METICULOUS_KEYED_SHA1     5

/*
 * BFD Diagnostic codes
 */
#define BFD_DIAG_NONE                                   0
#define BFD_DIAG_DETECT_TIMEOUT                         1
#define BFD_DIAG_ECHO_FAILED                            2
#define BFD_DIAG_NEIGHBOR_SIGNALED_SESSION_DOWN         3
#define BFD_DIAG_FORWARD_PLANE_RESET                    4
#define BFD_DIAG_PATH_DOWN                              5
#define BFD_DIAG_CONCATENATED_PATH_DOWN                 6
#define BFD_DIAG_ADMIN_DOWN                             7
#define BFD_DIAG_REVERSE_CONCATENATED_PATH_DOWN         8

/*
 * BFD Error codes
 */
typedef enum uc_bfd_error_e {
    UC_BFD_E_NONE = 0,
    UC_BFD_E_INTERNAL,
    UC_BFD_E_MEMORY,
    UC_BFD_E_PARAM,
    UC_BFD_E_RESOURCE,
    UC_BFD_E_EXISTS,
    UC_BFD_E_NOT_FOUND,
    UC_BFD_E_INIT
} _uc_fd_error_t;
/*
 * Simple Password authentication header format
 */
#define BFD_AUTH_PASSWORD_LENGTH_MAX 16
typedef struct
{
    uint8   auth_key_id;
    char    password[BFD_AUTH_PASSWORD_LENGTH_MAX];
} __attribute__ ((packed)) bfd_auth_header_password_t;

/*
 * SHA1 authentication header format
 */
#define BFD_AUTH_SHA1_KEY_LENGTH 20
#define BFD_BASE_MESSAGE_LENGTH 24
#define BFD_AUTH_SHA1_LENGTH 28
#define BFD_MAX_LENGTH (BFD_BASE_MESSAGE_LENGTH + BFD_AUTH_SHA1_LENGTH)
typedef struct
{
    uint8   auth_key_id;
    uint8   reserved;
    uint32  sequence;
    uint8   key[BFD_AUTH_SHA1_KEY_LENGTH];
} __attribute__ ((packed)) bfd_auth_header_sha1_t;

typedef struct
{
    uint8    type;
    uint8    length;

    union
    {
        bfd_auth_header_password_t    password;
        bfd_auth_header_sha1_t        sha1;
    } data;

} __attribute__ ((packed)) bfd_auth_header_t;

/*
 * BFD header format
 */
typedef struct
{
    /* Mandatory */
#ifdef LE_HOST
    unsigned int    diag:5,
                    version:3;
    unsigned int    multipoint:1,
                    demand_mode:1,
                    auth_present:1,
                    cpi:1,
                    final:1,
                    poll:1,
                    state:2;
#else
    unsigned int    version:3,
                    diag:5;
    unsigned int    state:2,
                    poll:1,
                    final:1,
                    cpi:1,
                    auth_present:1,
        demand_mode:1,
                    multipoint:1;
#endif

    uint8           detect_multiplier;
    uint8           length;
    uint32          my_discriminator;
    uint32          your_discriminator;
    uint32          desired_min_tx_interval;
    uint32          required_min_rx_interval;
    uint32          required_min_echo_rx_interval;

    /* Optional, if auth_present */
    bfd_auth_header_t auth;

} __attribute__ ((packed)) bfd_header_t;

/* kill value for RX/TX threads */
#define BFD_SIGNAL_KILL 0xffffffff

/*
 * SDK <--> BTE message formats
 * NOTE: all fields declared as uint32 to simplify endianness
 */

/*
 * BFD initialization message
 */
typedef struct {
    uint32   num_sessions;
    uint32   encap_bytes;
    uint32    num_auth_sha1_key;
    uint32    num_auth_sp_key;
    uint32    dma_num;
}bfd_msg_ctrl_init_t;

#define BFD_UPDATE_FLAG_SESSION_CREATE      0x1
#define BFD_UPDATE_FLAG_LOCAL_DISC          0x2
#define BFD_UPDATE_FLAG_LOCAL_MIN_TX        0x4
#define BFD_UPDATE_FLAG_LOCAL_MIN_RX        0x8
#define BFD_UPDATE_FLAG_LOCAL_MIN_ECHO_RX   0x10
#define BFD_UPDATE_FLAG_LOCAL_DIAG          0x20
#define BFD_UPDATE_FLAG_LOCAL_DEMAND        0x40
#define BFD_UPDATE_FLAG_LOCAL_DETECT_MULT   0x80
#define BFD_UPDATE_FLAG_SESSION_DESTROY     0x100
#define BFD_UPDATE_FLAG_SHA1_XMT_SEQ_INCR   0x200
#define BFD_UPDATE_FLAG_ENCAP               0x400
#define BFD_UPDATE_FLAGS_ALL 0x7ff

/*
 * BFD session update message
 */
typedef struct {
    uint32   sess_id;
    uint32   flags;
    uint32   passive;
    uint32   local_discriminator;
    uint32   remote_discriminator;
    uint32   local_min_tx;
    uint32   local_min_rx;
    uint32   local_min_echo_rx;
    uint32   local_demand;
    uint32   local_detect_mult;
    uint32   local_diag;
    uint32   auth_type;
    uint32   auth_key;
    uint32   xmt_auth_seq;
    uint32   l2l3l4_offset;
    uint32   l2l3l4_length;
    uint32   l2l3l4_type;
    uint32   tx_port;
    uint32   tx_cos;
    uint32   tx_pri;
    uint32   mep_id_offset;
    uint32   mep_id_length;
}bfd_msg_ctrl_sess_update_t;

/*
 * Encapsulation types
 */
#define BFD_ENCAP_TYPE_RAW      0
#define BFD_ENCAP_TYPE_V4UDP    1
#define BFD_ENCAP_TYPE_V6UDP    2

typedef struct {
    uint32   sess_id; /* in */
    uint32   enable;
    uint32   passive;
    uint32   local_discriminator;
    uint32   remote_discriminator;
    uint32   local_min_tx;
    uint32   remote_min_tx;
    uint32   local_min_rx;
    uint32   remote_min_rx;
    uint32   local_min_echo_rx;
    uint32   remote_min_echo_rx;
    uint32   local_demand;
    uint32   remote_demand;
    uint32   local_detect_mult;
    uint32   remote_detect_mult;
    uint32   local_diag;
    uint32   remote_diag;
    uint32   local_sess_state;
    uint32   remote_sess_state;
    uint32   auth_type;
    uint32   auth_key;
    uint32   xmt_auth_seq;
    uint32   rcv_auth_seq;
    uint32   l2l3l4_offset;
    uint32   l2l3l4_length;
    uint32   l2l3l4_type;
    uint32   tx_port;
    uint32   tx_cos;
    uint32   tx_pri;
    uint32   mep_id_offset;
    uint32   mep_id_length;
}bfd_msg_ctrl_sess_get_reply_t;

/*
 * BFD simple passwored authentication message
 *
 * set length to zero to disable entry
 */
typedef struct {
    uint32   index;
    uint32   length;
    uint8    password[BFD_AUTH_PASSWORD_LENGTH_MAX];
}bfd_msg_ctrl_auth_sp_t;

/*
 * BFD SHA1 authentication message
 */
typedef struct {
    uint32  index;
    uint32  enable;
    uint32  sequence;
    uint8   key[BFD_AUTH_SHA1_KEY_LENGTH];
}bfd_msg_ctrl_auth_sha1_t;

/* Maximum lengths
 * L2 + L3 + L4
 * L2 + 2 VLAN + IPV6 + GRE + IPV6 + UDP + BFD + SHA1 + FCS
 * 14 + 8 + 40 + 4 + 40 + 8 + 24 + 28 + 4
 */
#define BFD_MAX_ENCAP_LENGTH    114
#define BFD_MAX_PACKET_LENGTH   172

/*
 * BFD encapsulation message
 */
typedef struct {
    uint32   offset;  /* byte offset into encap table */
    uint32   length;
    uint8   data[BFD_MAX_ENCAP_LENGTH];
}bfd_msg_ctrl_encap_t;

/*
 * BFD stats
 */
typedef struct {
    uint32   sess_id;
    uint32   clear;
    uint32   addr;
}bfd_msg_ctrl_stat_req_t;

typedef struct {
    uint32   sess_id;
    uint32 packets_in; 
    uint32 packets_out; 
    uint32 packets_drop; 
    uint32 packets_drop_auth; 
}bfd_msg_ctrl_stat_reply_t;

/*
 * BFD control message
 */
typedef struct bfd_msg_ctrl_s {
    union {
        bfd_msg_ctrl_init_t in;
        bfd_msg_ctrl_sess_update_t su;
        bfd_msg_ctrl_sess_get_reply_t get_rpy;
        bfd_msg_ctrl_auth_sp_t sp;
        bfd_msg_ctrl_auth_sha1_t sha1;
        bfd_msg_ctrl_encap_t enc;
        bfd_msg_ctrl_stat_req_t cnt_req;
        bfd_msg_ctrl_stat_reply_t cnt_reply;
    } u;
}bfd_msg_ctrl_t;

/*
 * BFD event message
 */
#define BFD_BTE_EVENT_STATE                      0x0001
#define BFD_BTE_EVENT_REMOTESTATE_DIAG           0x0002
#define BFD_BTE_EVENT_DISCRIMINATOR              0x0004
#define BFD_BTE_EVENT_PARAMETER                  0x0008
#define BFD_BTE_EVENT_AUTHENTICATION             0x0010  
#define BFD_BTE_EVENT_ERROR                      0x0020

typedef union bfd_msg_event_s {
    uint32  words[2];
    struct {
#ifdef LE_HOST
        unsigned int    mclass:8,
                        events:8,
                        local_state:2,
                        remote_state:2,
                        remote_diag:5,
                        rsvd:7;
#else
        unsigned int    rsvd:7,
                        remote_diag:5,
                        remote_state:2,
                        local_state:2,
                        events:8,
                        mclass:8;
#endif
        uint16          sess_id;
        uint16          rsvd1;
    } s;
}bfd_msg_event_t;

#endif /* BFD_H_ */
